/*
 *  SymbolTable.h
 *  Compiler
 *
 *  Created by Jacopo De Stefani on 3/5/12.
 *  Copyright 2012 Politecnico di Milano. All rights reserved.
 *
 */

#ifndef EXTENDEDSYMBOLTABLE_H
#define EXTENDEDSYMBOLTABLE_H

#include "enums.h"
#include "SymbolTableAttributes.h"
#include "Writer.h"

typedef pair<string,SymbolTableAttributes*> SymbolTableEntry;
typedef pair<string,queue<TypesP>* > FunctionTableEntry;
typedef map<string,SymbolTableAttributes*> SymbolTable; 
typedef map<string,queue<TypesP>* > FunctionTable;

using namespace std;

//User types definition


class ExtendedSymbolTable
{
public:
        //Static method to access the singleton implementation
	static  ExtendedSymbolTable* getInstance();
	
	//Adds a new entry in the table with default values and identifier id.
	void addSymbolTableEntry(string identifier);
	
	//Adds a new entry in the table with default values and identifier id.
	void addFunctionTableEntry(string identifier);
	
	//Updates the attributes of a list of variables using currVarList.
	//Return the number of inserted elements
        int updateSymbolTable(TypesP type,ScopesP scope,bool routineFlag,bool isArg);
	
	//Updates the parameters' list for a given function using currTypeList;
	void updateTypeList(string identifier);
        
        //Check the correctness of actual parameters (type, order, number);
        bool checkCallParameters(string identifier);
	//Check the correctness of the scope
        bool checkScope(string identifier);
        
	//Modifiers of the list of variables
	void pushVar(string varId);
	void flushVarList();
	
	//Modifiers of the list of parameters
	void pushType(TypesP paramType);
	void flushTypeList();
    
        //Get & Set methods to access variables
        void setCurrScopeId(const string &id){currScopeId = id;};
        void setLastId(const string &id){lastId = id;};
        void setLastNum(int num){lastNum = num;};
        
        string getCurrScopeId(){return currScopeId;};
        string getLastId(){return lastId;};
        int getLastNum(){return lastNum;};
        
        //Gets attributes for a given entry in the symbol table
        SymbolTableAttributes getSymbolTableAttributes(string identifier);
        //Gets attributes for a given entry in the function table
        queue<TypesP> getFunctionParameters(string identifier);
        
        //Assigns a global address to the allocated identifier
        void globalAddress(string identifier);
        //Assigns a local address to the allocated identifier
        void localAddress(string identifier);
        //Sets to zero the counter for local addressing 
        void restartLocalAddress();
        //Check the existence of an identifier
        bool exists(string identifier);
	
private:
        //Default constructor
        ExtendedSymbolTable(){};
	//Singleton implementation of the Extended Symbol Table
        static ExtendedSymbolTable* uniqueInstance;
        //Symbol table
	SymbolTable symbolTable;
	//Function table
	FunctionTable functionTable;
	//Current list of variables whose allocation is deferred.
	list<string> currVarList;
	//Current list of types of parameters of a given function
	queue<TypesP> currTypeList;
        //Variable containing the identifier of the program
        string currScopeId;
        //Variable containing the last read identifier
        string lastId;
        //String containing either null or a duplicated identifier
        string dupId;
        //Variable containing the last read number
        int lastNum;
	//Counter for global addressing
        int globctr;
        //Counter for local addressing
        int locctr;
        
	string popVar(void);
	TypesP popType(void);
	void concVarList(queue<string> first,queue<string> second);
	void concTypeList(queue<TypesP> first,queue<TypesP> second);
	
};
#endif